package com.h117121.fashionshop.controller;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.support.SessionStatus;

import com.h117121.fashionshop.constant.AppConstant;
import com.h117121.fashionshop.controller.generic.GenericController;
import com.h117121.fashionshop.core.dom.Producer;
import com.h117121.fashionshop.core.dom.ProductQuery;
import com.h117121.fashionshop.core.dom.ProductType;
import com.h117121.fashionshop.validator.ProductQueryValidator;

@Controller
@RequestMapping("/search")
public class SearchController extends GenericController {
	@Autowired
	private ProductQueryValidator validator;
	@Autowired
	private MessageSource messageSource;

	public boolean isFormSubmission(HttpServletRequest request) {
		if (request.getParameter("searchType") != null
				&& !request.getParameter("searchType").isEmpty()) {
			if (request.getParameter("searchType").equals("quick")) {
				if (request.getParameter("keyWord") != null) {
					return true;
				}
			} else if (request.getParameter("searchType").equals("advance")) {
				if (request.getParameter("productName") != null
						|| request.getParameter("productType") != null
						|| request.getParameter("producerName") != null
						|| request.getParameter("priceFrom") != null
						|| request.getParameter("priceTo") != null) {
					return true;
				}
			}
		}

		return false;
	}

	@RequestMapping(method = RequestMethod.GET)
	public String showForm(HttpServletRequest request,
			@ModelAttribute("query") ProductQuery query, BindingResult errors,
			SessionStatus status) {
		setSearchPanel(request);

		if (isFormSubmission(request)) {

			validator.validate(query, errors);
			if (errors.hasErrors()) {
				return "SearchPage";
			}

			String page = request.getParameter("page");
			int indexPage = 0;

			if (page != null && !page.isEmpty()) {
				try {
					indexPage = Integer.parseInt(page);
					indexPage -= 1;
					if (indexPage < 0)
						indexPage = 0;
				} catch (NumberFormatException e) {
					indexPage = 0;
				}
			}

			request.setAttribute("searchResults", businessService
					.findByProductQuery(query, indexPage,
							AppConstant.NUM_ITEM_PER_PAGE));
			String paraURL = ((HttpServletRequest) request).getQueryString();
			if (paraURL.contains("&page=")) {
				request.setAttribute("pageURL",
						paraURL.substring(0, paraURL.indexOf("&page=")));
			} else {
				request.setAttribute("pageURL", paraURL);
			}
		}

		return "SearchPage";
	}

	private void setSearchPanel(HttpServletRequest request) {
		if (request.getParameter("searchType") != null
				&& request.getParameter("searchType").equals("quick")) {
			request.setAttribute("searchType", "quick");
		} else {
			request.setAttribute("searchType", "advance");
		}
	}

	@ModelAttribute("productTypes")
	public Map<String, String> populateProductTypesList(Locale locale) {
		Map<String, String> productTypes = new LinkedHashMap<String, String>();
		List<ProductType> list = businessService.getAllProductType();

		productTypes.put(null, messageSource.getMessage(
				"message.choose_a_product_type", null, locale));
		for (ProductType productType : list) {
			productTypes.put(productType.getName(), productType.getName());
		}
		return productTypes;
	}

	@ModelAttribute("producerNames")
	public Map<String, String> populateProducerNamesList(Locale locale) {
		Map<String, String> producerNames = new LinkedHashMap<String, String>();
		List<Producer> list = businessService.getAllProducer();

		producerNames.put(null, messageSource.getMessage(
				"message.choose_a_producer", null, locale));
		for (Producer producer : list) {
			producerNames.put(producer.getName(), producer.getName());
		}
		return producerNames;
	}
}
